package com.ruoyi.oss.service.impl;

import cn.xuyanwu.spring.file.storage.FileStorageService;
import cn.xuyanwu.spring.file.storage.platform.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.enums.YesOrNo;
import com.ruoyi.oss.model.attr.*;
import com.ruoyi.oss.service.StoragePlatformService;
import com.ruoyi.oss.mapper.StoragePlatformMapper;
import com.ruoyi.oss.entity.PlatformType;
import com.ruoyi.oss.entity.StoragePlatform;
import com.ruoyi.oss.service.PlatformTypeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author shejiangbo
 * @description 针对表【storage_platform(存储平台)】的数据库操作Service实现
 * @createDate 2023-05-09 16:00:28
 */
@Service
@Slf4j
public class StoragePlatformServiceImpl extends ServiceImpl<StoragePlatformMapper, StoragePlatform>
    implements StoragePlatformService {

    @Autowired
    FileStorageService fileStorageService;

    @Autowired
    PlatformTypeService platformTypeService;

    public List<StoragePlatform> listEnable() {
        QueryWrapper<StoragePlatform> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(true, "enable_storage", YesOrNo.YES.getValue());
        return this.list(queryWrapper);
    }

    public void init() throws ClassNotFoundException {
        List<StoragePlatform> storagePlatforms = listEnable();
        for (StoragePlatform storagePlatform : storagePlatforms) {
            if(storagePlatform.getPlatformAttr()!=null){
                pushNewStorage(storagePlatform);
            }else{
                log.error("StoragePlatform PlatformAttr is null:{},{}",storagePlatform.getPlatformName(),storagePlatform.getPlatformType());
            }
        }
    }

    public StoragePlatform findkey(String platformKey) {
        QueryWrapper<StoragePlatform> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(true, "platform_key", platformKey);
        return this.getOne(queryWrapper);
    }

    public void pushNewStorage(StoragePlatform storagePlatform) throws ClassNotFoundException {
        PlatformType platformType = platformTypeService.findCode(storagePlatform.getPlatformType());
        if (platformType == null) {
            log.debug("PlatformType is null");
            return;
        }
        Class<?> cl = Class.forName(platformType.getPlateformClass());
        if (cl.equals(LocalPlusFileStorage.class)) {
            LocalPlusFileStorage localPlusFileStorage = genLocalPlusFileStorage(storagePlatform);
            pushNewStorage(localPlusFileStorage);
        } else if (cl.equals(MinIOFileStorage.class)) {
            MinIOFileStorage minIOFileStorage = genMinIOFileStorage(storagePlatform);
            pushNewStorage(minIOFileStorage);
        } else if (cl.equals(QiniuKodoFileStorage.class)) {
            QiniuKodoFileStorage minIOFileStorage = genQiniuKodoFileStorage(storagePlatform);
            pushNewStorage(minIOFileStorage);
        } else if (cl.equals(TencentCosFileStorage.class)) {
            TencentCosFileStorage minIOFileStorage = genTencentCosFileStorage(storagePlatform);
            pushNewStorage(minIOFileStorage);
        } else if (cl.equals(AliyunOssFileStorage.class)) {
            AliyunOssFileStorage minIOFileStorage = genAliyunOssFileStorage(storagePlatform);
            pushNewStorage(minIOFileStorage);
        } else if (cl.equals(HuaweiObsFileStorage.class)) {
            HuaweiObsFileStorage minIOFileStorage = genHuaweiObsFileStorage(storagePlatform);
            pushNewStorage(minIOFileStorage);
        }
    }

    public LocalPlusFileStorage genLocalPlusFileStorage(StoragePlatform storagePlatform) {
        LocalPlusFileStorage localPlusFileStorage = new LocalPlusFileStorage();
        LocalPlusConfig config = (LocalPlusConfig)storagePlatform.getPlatformAttr();
        localPlusFileStorage.setPlatform(storagePlatform.getPlatformKey());
        localPlusFileStorage.setStoragePath(config.getStoragePath());
        localPlusFileStorage.setBasePath(storagePlatform.getBasePath());
        localPlusFileStorage.setDomain(storagePlatform.getDoMain());
        return localPlusFileStorage;
    }

    public MinIOFileStorage genMinIOFileStorage(StoragePlatform storagePlatform) {
        MinIOFileStorage minIOFileStorage = new MinIOFileStorage();
        MinioConfig minioConfig = (MinioConfig)storagePlatform.getPlatformAttr();
        minIOFileStorage.setPlatform(storagePlatform.getPlatformKey());
        minIOFileStorage.setBasePath(storagePlatform.getBasePath());
        minIOFileStorage.setDomain(storagePlatform.getDoMain());
        minIOFileStorage.setAccessKey(minioConfig.getAccessKey());
        minIOFileStorage.setBucketName(minioConfig.getBucketName());
        minIOFileStorage.setSecretKey(minioConfig.getSecretKey());
        minIOFileStorage.setEndPoint(minioConfig.getEndPoint());
        return minIOFileStorage;
    }

    public QiniuKodoFileStorage genQiniuKodoFileStorage(StoragePlatform storagePlatform) {
        QiniuKodoFileStorage minIOFileStorage = new QiniuKodoFileStorage();
        QiniuKodoConfig minioConfig = (QiniuKodoConfig)storagePlatform.getPlatformAttr();
        minIOFileStorage.setPlatform(storagePlatform.getPlatformKey());
        minIOFileStorage.setBasePath(storagePlatform.getBasePath());
        minIOFileStorage.setDomain(storagePlatform.getDoMain());
        minIOFileStorage.setAccessKey(minioConfig.getAccessKey());
        minIOFileStorage.setBucketName(minioConfig.getBucketName());
        minIOFileStorage.setSecretKey(minioConfig.getSecretKey());
        // minIOFileStorage.setRegion(minioConfig.getRegion());
        return minIOFileStorage;
    }

    public TencentCosFileStorage genTencentCosFileStorage(StoragePlatform storagePlatform) {
        TencentCosFileStorage minIOFileStorage = new TencentCosFileStorage();
        TencentCosConfig minioConfig = (TencentCosConfig)storagePlatform.getPlatformAttr();
        minIOFileStorage.setPlatform(storagePlatform.getPlatformKey());
        minIOFileStorage.setBasePath(storagePlatform.getBasePath());
        minIOFileStorage.setDomain(storagePlatform.getDoMain());
        minIOFileStorage.setSecretId(minioConfig.getAccessId());
        minIOFileStorage.setBucketName(minioConfig.getBucketName());
        minIOFileStorage.setSecretKey(minioConfig.getSecretKey());
        minIOFileStorage.setRegion(minioConfig.getRegion());
        return minIOFileStorage;
    }

    public AliyunOssFileStorage genAliyunOssFileStorage(StoragePlatform storagePlatform) {
        AliyunOssFileStorage minIOFileStorage = new AliyunOssFileStorage();
        AliyunOssConfig minioConfig = (AliyunOssConfig)storagePlatform.getPlatformAttr();
        minIOFileStorage.setPlatform(storagePlatform.getPlatformKey());
        minIOFileStorage.setBasePath(storagePlatform.getBasePath());
        minIOFileStorage.setDomain(storagePlatform.getDoMain());
        minIOFileStorage.setAccessKey(minioConfig.getAccessKey());
        minIOFileStorage.setBucketName(minioConfig.getBucketName());
        minIOFileStorage.setSecretKey(minioConfig.getSecretKey());
        minIOFileStorage.setEndPoint(minioConfig.getEndPoint());
        return minIOFileStorage;
    }

    public HuaweiObsFileStorage genHuaweiObsFileStorage(StoragePlatform storagePlatform) {
        HuaweiObsFileStorage minIOFileStorage = new HuaweiObsFileStorage();
        HuaweiObsConfig minioConfig = (HuaweiObsConfig)storagePlatform.getPlatformAttr();
        minIOFileStorage.setPlatform(storagePlatform.getPlatformKey());
        minIOFileStorage.setBasePath(storagePlatform.getBasePath());
        minIOFileStorage.setDomain(storagePlatform.getDoMain());
        minIOFileStorage.setAccessKey(minioConfig.getAccessKey());
        minIOFileStorage.setBucketName(minioConfig.getBucketName());
        minIOFileStorage.setSecretKey(minioConfig.getSecretKey());
        minIOFileStorage.setEndPoint(minioConfig.getEndPoint());
        return minIOFileStorage;
    }

    public void pushNewStorage(FileStorage fileStorage) {
        if (fileStorage == null) {
            return;
        }
        CopyOnWriteArrayList<FileStorage> list = fileStorageService.getFileStorageList();
        list.add(fileStorage);
    }

    public void removeStorage(String platformKey, boolean removeEntity) {
        if (StringUtils.isBlank(platformKey)) {
            return;
        }
        CopyOnWriteArrayList<FileStorage> list = fileStorageService.getFileStorageList();
        FileStorage myLocal = fileStorageService.getFileStorage(platformKey);
        list.remove(myLocal);
        myLocal.close();// 释放资源
        if (removeEntity) {
            QueryWrapper<StoragePlatform> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(true, "platform_key", platformKey);
            this.remove(queryWrapper);
        }
    }

    public void setDefaultStorage(String platformKey) {
        fileStorageService.getProperties().setDefaultPlatform(platformKey);
    }

    @Override
    public String getDefaultStorage() {
        return fileStorageService.getProperties().getDefaultPlatform();
    }

}
